<script setup>
import {ref, defineExpose, defineEmits} from 'vue'
import SelectBox from './SelectBox.vue'
import {Plus} from '@element-plus/icons-vue'
import {QuillEditor} from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
import {pubArticle, detailArticle, editArticle} from '@/api/article.js'
import {baseURL} from '@/utils/request.js'
import axios from 'axios'

const emit = defineEmits(['success'])

const drawer = ref(false)
const pubForm = ref({
  title: '',
  cate_id: '',
  content: '',
  cover_img: '',  // file类型
  state: '',
})
// 图片上传相关逻辑
const imgUrl = ref('')
const imgChange = (uploadFile) => {
  console.log(uploadFile)
  // 拿到文件地址，赋值给imgUrl，用来预览图片
  imgUrl.value = URL.createObjectURL(uploadFile.raw)
  console.log(imgUrl.value)
  // 立刻将图片文件对象存入pubForm.value.cover_img中，将来用来提交（后台接口要求是formData格式）
  pubForm.value.cover_img = uploadFile.raw
}
// 组件对外暴露一个方法open，基于open传来的参数，区分添加还是编辑
// open({})=>表单无需渲染 添加
// open({id,cate_name,...})=>表单需要渲染 编辑
const editorRef = ref()
const open = async (row) => {
  drawer.value = true
  if (row.id) {
    // 编辑
    // 需要基于 row.id 发送请求获取编辑对应的详情数据，进行回显
    // 之前这个row里面有我们想要的全部数据，所以直接展开赋值即可
    // 但是这个row里面有些字段没有，只能掉详情接口拿到全部数据进行回显
    const res = await detailArticle({id: row.id})
    console.log(res.data.data)
    pubForm.value = res.data.data
    // 图片需要单独处理回显
    imgUrl.value = baseURL + pubForm.value.cover_img

    //正常情况都支持地址和file对象
    // 注意提交给后台，需要的图片数据格式，是file对象格式，需要将图片地址，转换成file对象，存储起来
    pubForm.value.cover_img = await imageUrlToFile(imgUrl.value, pubForm.value.cover_img)

  } else {
    //添加
    //添加之前需要重置表单数据
    pubForm.value = {...pubForm}
    //图片上传地址和富文本编辑器内容需要手动重置
    imgUrl.value = ''
    editorRef.value.setHTML('')
  }
}

async function imageUrlToFile(url, fileName) {
  try {
    // 第一步：使用axios获取网络图片数据
    const response = await axios.get(url, {responseType: 'arraybuffer'});
    const imageData = response.data
    // 第二步：将图片数据转换为Blob对象
    const blob = new Blob([imageData], {type: response.headers['content-type']})
    // 第三步：创建一个新的File对象
    const file = new File([blob], fileName, {type: blob.type})
    return file
  } catch (error) {
    throw error
  }
}

defineExpose({
  open
})

// 发布相关
const pubBtn = async (state) => {
  // 将已发布或草稿状态存入pubForm
  pubForm.value.state = state
  // 当前接口需要的是formData对象
  // 上面是js的普通对象，要转成formData对象
  const fd = new FormData()
  for (let key in pubForm.value) {
    fd.append(key, pubForm.value[key])
  }
// 发请求
  if (pubForm.value.id) {
    // 编辑
    await editArticle(fd)
    ElMessage.success('编辑成功')
    // 通知父组件更新列表
    emit('success', 'edit')

  } else {
    // 添加
    await pubArticle(fd)
    ElMessage.success('添加成功')
    // 通知父组件更新列表
    emit('success', 'add')
  }
  drawer.value = false
}
</script>

<template>
  <el-drawer
      v-model="drawer"
      title="发布文章"
      sise="100%"
  >
    <el-form :model="pubForm" ref="pubFormRef">
      <el-form-item label="文章标题" prop="title">
        <el-input v-model="pubForm.title" placeholder="请输入标题"></el-input>
      </el-form-item>
      <el-form-item label="文章分类" prop="cate_id">
        <SelectBox v-model="pubForm.cate_id" width="100%"></SelectBox>
      </el-form-item>
      <el-form-item label="文章封面" prop="cover_img">
        <!-- 此处需要关闭element-plus的自动上传，并且不需要配置action等参数
        因为此处只需要做前端的本地预览图片即可，无需再提交之前上传图片
        语法：URL.createObjectURL(...) 创建本地预览地址来预览
        -->
        <el-upload
            class="avatar-uploader"
            :show-file-list="false"
            :auto-upload="false"
            :on-change="imgChange"
        >
          <img v-if="imgUrl" :src="imgUrl" class="avatar"/>
          <el-icon v-else class="avatar-uploader-icon">
            <Plus/>
          </el-icon>
        </el-upload>
      </el-form-item>
      <el-form-item label="文章内容" prop="content">
        <div class="editor">
          <QuillEditor ref="editorRef" v-model:content="pubForm.content" content-type="html" theme="snow"/>
        </div>
      </el-form-item>
      <el-form-item>
        <el-button @click="pubBtn('已发布')" type="primary">发布</el-button>
        <el-button @click="pubBtn('草稿')" type="info">草稿</el-button>
      </el-form-item>
    </el-form>
  </el-drawer>
</template>

<style scoped lang="scss">
.avatar-uploader {
  :deep() {
    .avatar {
      width: 178px;
      height: 178px;
      display: block;
    }

    .el-upload {
      border: 1px dashed var(--el-border-color);
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
      transition: var(--el-transition-duration-fast);
    }

    .el-upload:hover {
      border-color: var(--el-color-primary);
    }

    .el-icon.avatar-uploader-icon {
      font-size: 28px;
      color: #8c939d;
      width: 178px;
      height: 178px;
      text-align: center;
    }
  }
}

.editor {
  width: 100%;

  :deep(.ql-editor) {
    min-height: 200px;
  }
}
</style>
